<?php

/**
 * This file is part of the Codizer package.
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 *
 * @copyright   Copyright (c) 2010 Advisa (http://www.advisa.fr)
 * @author      Codizer Core Team <team@codizer.org>
 * @package     Codizer
 */

class f_context_User
{
	private static $instance;
	
	private $useACL = false;
	private $user;
	private $rights;
    private $context;
	
	/**
	 * @return f_context_User
	 */
	private function __construct($userContext)
	{
        $this->context = $userContext;
        
		$context = f_core_Context::getInstance();
		
		$config = f_loader_Config::getInstance()->getParameters("default");
		
		if(isset($config['useACL']))
		{
			if($config['useACL'] == "1")
			{
				$this->useACL = true;
			}
		}

		if($context->contextExist($this->context))
		{
			$context = $context->getContext($this->context);
			if($context instanceof f_context_User)
			{
				$this->rights = $context->getRights();
				$this->user = $context->getUser();
			}		
		}
		
		return $this;
	}
	
	/**
	 * Get singleton instance
	 *
	 * @return f_context_User
	 */
	public static function getInstance($userContext = "")
	{
        $userContext = "user".$userContext;

		if(self::$instance[$userContext] === null)
		{
			self::$instance[$userContext] = new self($userContext);
		}
        
		return self::$instance[$userContext];
	}
	
	/**
	 * Set user parameters, can be an object, array, string, etc...
	 *
	 * @param mixed $user
	 * @return f_context_User
	 */
	public function setUser($user)
	{
		$this->user = $user;
		$this->saveInSession();
		return $this;
	}
	
	/**
	 * Retrieve the user setted in context
	 *
	 * @return mixed
	 */
	public function getUser()
	{
		return $this->user;
	}
    
	/**
	 * Add a user right
	 *
	 * @param string $ruleName
	 * @return f_context_User
	 */
	public function addRight($ruleName)
	{
		$this->rights[$ruleName] = true;
		$this->saveInSession();
		return $this;
	}
	
	/**
	 * Check if user has right in context
	 *
	 * @param string $ruleName
	 * @return boolean
	 */
	public function hasRight($ruleName, $type = "AND")
	{
		if($this->useACL == true)
		{
            if(is_array($ruleName) && isset($type))
            {
                switch($type)
                {
                    //if one of the rule doen't exit, it return false
                    default:
                        foreach($ruleName as $rule)
                        {
                            if(!isset($this->rights[$rule]))
                            {
                                return false;
                            }
                        }

                        return true;
                    break;

                    //if one of the rule exit, it return true
                    case "OR":
                        foreach($ruleName as $rule)
                        {
                            if(isset($this->rights[$rule]))
                            {
                                return true;
                            }
                        }

                        return false;
                    break;
                }
            }
            else
            {
                return isset($this->rights[$ruleName]);
            }
		}
		return true;
	}
	
	/**
	 * Remove one setted right in context
	 *
	 * @param string $ruleName
	 * @return f_context_User
	 */
	public function removeRight($ruleName)
	{
		if(isset($this->rights[$ruleName]))
		{
			unset($this->rights[$rulename]);
		}
		$this->saveInSession();
		return $this;
	}
	
	/**
	 * Get all user rights from context
	 *
	 * @return array|null
	 */
	public function getRights()
	{
		return $this->rights;
	}
	
	/**
	 * Remove all user rights from context
	 *
	 * @return f_context_User
	 */
	public function removeRights()
	{
		$this->rights = null;
		$this->saveInSession();
		return $this;
	}
	
	/**
	 * Remove the user from context
	 */
	public function removeUser()
	{
		$this->removeUserContext();
	}
		
	/**
	 * Save datas in session
	 *
	 */
	private function saveInSession()
	{
		$context = f_core_Context::getInstance();
		$context->setContext($this->context, $this);
	}
	
	/**
	 * Remove the user session
	 *
	 */
	private function removeUserContext()
	{
		$context = f_core_Context::getInstance();
		$context->removeContext($this->context);
	}
}